package com.quectel.cms.util;

import com.google.common.base.Preconditions;
import com.quectel.cms.constants.CmsRedisCacheConstants;
import com.quectel.cms.constants.CmsSystemConstants;
import com.quectel.cms.interceptor.LoginUserSession;
import com.quectel.constant.global.SystemConstants;
import com.quectel.util.common.JacksonUtils;
import com.quectel.util.redis.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * session管理器
 *
 * @author: caolu
 * @email: louis.cao@quectel.com
 * @date: 2022-07-27 11:26:00
 */
@Slf4j
public class SessionHolder {

    public static LoginUserSession buildRedisSession(LoginUserSession session) {
        //token绑定人员
        RedisUtils.set(CmsRedisCacheConstants.TOKEN_USER_PREFIX + session.getToken(),
                JacksonUtils.toJsonString(session), CmsRedisCacheConstants.TOKEN_DEFAULT_TIMEOUT, TimeUnit.MINUTES);
        //人员绑定token 方便禁用清除
        RedisUtils.hSet(CmsRedisCacheConstants.USER_TOKEN_PREFIX + session.getUserId(), session.getToken(),
                SystemConstants.EMPTY_STR, CmsRedisCacheConstants.TOKEN_DEFAULT_TIMEOUT, TimeUnit.MINUTES);
        //重要的数据不返回前端
        session.setOfficialAccountsType(null);
        session.setAppId(null);
        session.setOpenId(null);
        return session;
    }

    public static LoginUserSession getSysUser() {

        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        Preconditions.checkArgument(requestAttributes != null, "ServletRequestAttributes is null");
        HttpServletRequest httpServletRequest = requestAttributes.getRequest();
        Preconditions.checkArgument(httpServletRequest != null, "HttpServletRequest is null");

        LoginUserSession session = (LoginUserSession) httpServletRequest.getAttribute(CmsSystemConstants.USER_SESSION_SAVE_KEY);
        if (session != null) {
            return session;
        }

        String token = httpServletRequest.getHeader("token");
        if (StringUtils.isEmpty(token)) {
            token = httpServletRequest.getParameter("token");
        }
        if (StringUtils.isNotBlank(token)) {
            //说明是放行的却传了token需要查询一下redis
            String loginUserInfoStr = RedisUtils.get(CmsRedisCacheConstants.TOKEN_USER_PREFIX + token);
            if (StringUtils.isNotBlank(loginUserInfoStr)) {
                return JacksonUtils.parse(loginUserInfoStr, LoginUserSession.class);
            }
            return session;
        }
        return null;
    }

    /**
     * 获取当前登陆用户Id
     *
     * @return
     */
    public static Long getSysUserId() {
        LoginUserSession loginUser = getSysUser();
        return loginUser.getUserId();
    }


    /**
     * 删除用户的token
     *
     * @param id
     */
    public static void removeUserToken(Long id) {
        //需要踢出已经授权的token
        Map<String, String> tokens = RedisUtils.hGetAll(CmsRedisCacheConstants.USER_TOKEN_PREFIX + id);
        if (tokens != null) {
            tokens.forEach((k, v) -> RedisUtils.del(CmsRedisCacheConstants.TOKEN_USER_PREFIX + k));
        }
        RedisUtils.del(CmsRedisCacheConstants.USER_TOKEN_PREFIX + id);
    }

    /**
     * 退出当前session
     */
    public static void logout() {
        LoginUserSession session = getSysUser();

        if (session == null){
            return;
        }
        //删除token绑定人员
        RedisUtils.del(CmsRedisCacheConstants.TOKEN_USER_PREFIX + session.getToken());
        //删除人员所绑定的当前token
        RedisUtils.hDel(CmsRedisCacheConstants.USER_TOKEN_PREFIX + session.getUserId(), session.getToken());
    }
}
